home *** CD-ROM | disk | FTP | other *** search
- /*
- * $Log: arcio.c,v $
- * Revision 1.2 88/04/11 18:01:16 hyc
- * added support for squashing. (changed max hdrver from 8 to 9)
- *
- * Revision 1.1 88/04/11 17:59:43 hyc
- * Initial revision
- *
- * Revision 1.3 87/12/19 04:25:24 hyc
- * As before, different location tho.
- *
- * Revision 1.2 87/12/19 04:23:21 hyc
- * Fix problem caused by indent(?) screwing up line boundaries...
- *
- * Revision 1.1 87/12/19 04:21:23 hyc
- * Initial revision
- *
- * Revision 1.4 87/08/13 17:03:24 hyc
- * Run thru the indent program...
- * Revision 1.3 87/07/21 11:41:29 hyc *** empty
- * log message ***
- *
- * Revision 1.2 87/07/21 08:19:45 hyc *** empty log message ***
- *
- */
-
- /*
- * ARC - Archive utility - ARCIO
- *
- * Version 2.49, created on 07/25/86 at 16:44:23
- *
- * (C) COPYRIGHT 1985,86 by System Enhancement Associates; ALL RIGHTS RESERVED
- *
- * By: Thom Henderson
- *
- * Description: This file contains the file I/O routines used to manipulate an
- * archive.
- *
- * Language: Computer Innovations Optimizing C86
- */
- #include <stdio.h>
- #include "arc.h"
-
- INT
- readhdr(hdr, f) /* read a header from an archive */
- struct heads *hdr; /* storage for header */
- FILE *f; /* archive to read header from */
- {
- #ifndef MSDOS
- unsigned char dummy[28];
- INT i, j, k;
- #endif
- char name[13]; /* filename buffer */
- INT try = 0;/* retry counter */
- static INT first = 1; /* true only on first read */
-
- if (!f) /* if archive didn't open */
- return 0; /* then pretend it's the end */
- if (feof(f)) /* if no more data */
- return 0; /* then signal end of archive */
-
- if (fgetc(f) != 26) { /* check archive validity */
- if (warn) {
- printf("An entry in %s has a bad header.", arcname);
- nerrs++;
- }
- while (!feof(f)) {
- try++;
- if (fgetc(f) == 26) {
- ungetc(hdrver = fgetc(f), f);
- if (hdrver >= 0 && hdrver <= 9)
- break;
- }
- }
-
- if (feof(f) && first)
- arc_abort("%s is not an archive", arcname);
-
- if (warn)
- printf(" %d bytes skipped.\n", try);
-
- if (feof(f))
- return 0;
- }
- hdrver = fgetc(f); /* get header version */
- if (hdrver < 0)
- arc_abort("Invalid header in archive %s", arcname);
- if (hdrver == 0)
- return 0; /* note our end of archive marker */
- if (hdrver > 9) {
- fread(name, sizeof(char), 13, f);
- #ifdef MTS
- atoe(name, strlen(name));
- #endif
- printf("I don't know how to handle file %s in archive %s\n",
- name, arcname);
- printf("I think you need a newer version of ARC.\n");
- exit(1);
- }
- /* amount to read depends on header type */
-
- if (hdrver == 1) { /* old style is shorter */
- fread(hdr, sizeof(struct heads) - sizeof(long int), 1, f);
- hdrver = 2; /* convert header to new format */
- hdr->length = hdr->size; /* size is same when not
- * packed */
- } else
- #ifdef MSDOS
- fread(hdr, sizeof(struct heads), 1, f);
- #else
- fread(dummy, 27, 1, f);
-
- for (i = 0; i < 13; hdr->name[i] = dummy[i], i++);
- #ifdef MTS
- (void) atoe(hdr->name, strlen(hdr->name));
- #endif
- hdr->size = (LONG) ((dummy[16] << 24) + (dummy[15] << 16) + (dummy[14] << 8)
- + dummy[13]);
- hdr->date = (short) ((dummy[18] << 8) + dummy[17]);
- hdr->time = (short) ((dummy[20] << 8) + dummy[19]);
- hdr->crc = (short) ((dummy[22] << 8) + dummy[21]);
- hdr->length = (LONG) ((dummy[26] << 24) + (dummy[25] << 16)
- + (dummy[24] << 8) + dummy[23]);
- #endif
-
- if (hdr->date > olddate
- || (hdr->date == olddate && hdr->time > oldtime)) {
- olddate = hdr->date;
- oldtime = hdr->time;
- }
- first = 0;
- return 1; /* we read something */
- }
-
- put_int(number, f) /* write a 2 byte integer */
- INT number;
- FILE *f;
- {
- fputc(number & 255, f);
- fputc(number >> 8, f);
- }
-
- put_long(number, f) /* write a 4 byte integer */
- LONG number;
- FILE *f;
- {
- put_int(number & 0xFFFF, f);
- put_int(number >> 16, f);
- }
-
- INT
- writehdr(hdr, f) /* write a header to an archive */
- struct heads *hdr; /* header to write */
- FILE *f; /* archive to write to */
- {
- fputc(26, f); /* write out the mark of ARC */
- fputc(hdrver, f); /* write out the header version */
- if (!hdrver) /* if that's the end */
- return; /* then write no more */
- #ifdef MSDOS
- fwrite(hdr, sizeof(struct heads), 1, f);
- #else
- /* byte/word ordering hassles... */
- #ifdef MTS
- etoa(hdr->name, strlen(hdr->name));
- #endif
- fwrite(hdr->name, 1, 13, f);
- put_long(hdr->size, f);
- put_int(hdr->date, f);
- put_int(hdr->time, f);
- put_int(hdr->crc, f);
- put_long(hdr->length, f);
- #endif
-
- /* note the newest file for updating the archive timestamp */
-
- if (hdr->date > arcdate
- || (hdr->date == arcdate && hdr->time > arctime)) {
- arcdate = hdr->date;
- arctime = hdr->time;
- }
- }
-
- INT
- putc_tst(c, t) /* put a character, with tests */
- char c; /* character to output */
- FILE *t; /* file to write to */
- {
- if (t)
- #ifdef BSD
- fputc(c, t);
- #else
- if (fputc(c, t) == EOF)
- arc_abort("Write fail (disk full?)");
- #endif
- }
-
- /*
- * NOTE: The filecopy() function is used to move large numbers of bytes from
- * one file to another. This particular version has been modified to improve
- * performance in Computer Innovations C86 version 2.3 in the small memory
- * model. It may not work as expected with other compilers or libraries, or
- * indeed with different versions of the CI-C86 compiler and library, or with
- * the same version in a different memory model.
- *
- * The following is a functional equivalent to the filecopy() routine that
- * should work properly on any system using any compiler, albeit at the cost
- * of reduced performance:
- *
- * filecopy(f,t,size)
- * FILE *f, *t; long size;
- * {
- * while(size--)
- * putc_tst(fgetc(f),t);
- * }
- */
- #ifdef MSDOS
- #include <fileio2.h>
-
- filecopy(f, t, size) /* bulk file copier */
- FILE *f, *t; /* files from and to */
- long size; /* bytes to copy */
- {
- char *buf; /* buffer pointer */
- char *alloc();/* buffer allocator */
- unsigned int bufl; /* buffer length */
- unsigned int coreleft(); /* space available reporter */
- unsigned int cpy; /* bytes being copied */
- long floc, tloc, fseek(); /* file pointers, setter */
- struct regval reg; /* registers for DOS calls */
-
- if ((bufl = coreleft()) < 1000) /* see how much space we have */
- arc_abort("Out of memory");
- bufl -= 1000; /* fudge factor for overhead */
- if (bufl > 60000)
- bufl = 60000; /* avoid choking alloc() */
- if (bufl > size)
- bufl = size; /* avoid wasting space */
- buf = alloc(bufl); /* allocate our buffer */
-
- floc = fseek(f, 0L, 1); /* reset I/O system */
- tloc = fseek(t, 0L, 1);
-
- segread(®.si); /* set segment registers for DOS */
-
- while (size > 0) { /* while more to copy */
- reg.ax = 0x3F00;/* read from handle */
- reg.bx = filehand(f);
- reg.cx = bufl < size ? bufl : size; /* amount to read */
- reg.dx = buf;
- if (sysint21(®, ®) & 1)
- arc_abort("Read fail");
-
- cpy = reg.ax; /* amount actually read */
- reg.ax = 0x4000;/* write to handle */
- reg.bx = filehand(t);
- reg.cx = cpy;
- reg.dx = buf;
- sysint21(®, ®);
-
- if (reg.ax != cpy)
- arc_abort("Write fail (disk full?)");
-
- size -= (long) cpy;
- }
-
- free(buf); /* all done with buffer */
- }
- #else
-
- filecopy(f, t, size) /* bulk file copier */
- FILE *f, *t; /* files from and to */
- LONG size; /* bytes to copy */
- {
- char *buf; /* buffer pointer */
- char *malloc(); /* buffer allocator */
- unsigned int bufl; /* buffer length */
- unsigned int cpy; /* bytes being copied */
- #ifdef MTS
- #define MTEXT 0x0010
- #endif
-
- bufl = 60000;
- if (bufl > size)
- bufl = size; /* don't waste space */
-
- buf = malloc(bufl);
-
- while (size > 0) {
- cpy = fread(buf, sizeof(char), bufl < size ? bufl : size, f);
- #ifdef MTS
- if ((f->_fmode & MTEXT) && !image)
- etoa(buf, cpy);
- #endif
- if (fwrite(buf, sizeof(char), cpy, t) != cpy)
- arc_abort("Write fail (no space?)");
- size -= cpy;
- }
-
- free(buf);
- }
- #endif
-